今天是倒數最後一天的前夕了,雖然可能看不完基礎語法但是收穫也是頗多,那我們繼續來看。
可選鏈是一種可以在當前值可能為 nil 的狀況下還可以請求和調用屬性、方法及下標方法。如果可選值有值,那麼就調用成功,反之如果是 nil ,那麼就返回 nil 。如果有多個調用連接再一起,其中只要一個環節為 nil 那麼整個調用鏈就會失敗,及回傳 nil。
可選值後面可以放 ? 跟 ! 。驚嘆號就是強制解開他的值。他們兩個的差別是一個調用如果為 nil 就會失敗,另一個則是直接觸發運行錯誤。
下面來看官方舉例來解釋可選鏈的方式跟強制解包的不同。
class Person {
var residence: Residence?
}
class Residence {
var numberOfRooms = 1
}
照上面的例子來看,如果是驚嘆號的話,因為 numberOfRooms 有一個整數 1 所以不會報錯
如果他是像下面這樣
class Person {
var residence: Residence!
}
class Residence {
var numberOfRooms = nil
}
會直接報錯就不會繼續執行了。
你可以通過可選鏈式可以調用多層屬性、方法和下標。這樣可以在複雜的模型中向下訪問各種子屬性,並且判斷能否訪問子屬性的屬性、方法和下標。
來看一下官方的例子
class Person {
var residence: Residence?
}
接下來定義一下 Residence
class Residence {
var rooms: [Room] = []
var numberOfRooms: Int {
return rooms.count
}
subscript(i: Int) -> Room {
get {
return rooms[i]
}
set {
rooms[i] = newValue
}
}
func printNumberOfRooms() {
print("The number of rooms is \(numberOfRooms)")
}
var address: Address?
}
然後是 Room 的定義
class Room {
let name: String
init(name: String) { self.name = name }
}
還有 Address
class Address {
var buildingName: String?
var buildingNumber: String?
var street: String?
func buildingIdentifier() -> String? {
if buildingName != nil {
return buildingName
} else if let buildingNumber = buildingNumber, let street = street {
return "\(buildingNumber) \(street)"
} else {
return nil
}
}
}
現在 Residence 裡面有存儲 Room 的 Array,numberOfRoom 是計算屬性,會返回 rooms Array 的 count 屬性。
Address 提供了 bulidingIdentifier 方法,返回 String? 。如果 buildingName 有值則返回 buildingName。 如果 buildingNumber 和 street 都有值則發回兩者拼接的字串。否則就返回 nil
可以用訪問的方式來看看定義的存儲行屬性有沒有值。
let john = Person()
if let roomCount = john.residence?.numberOfRooms {
print("John's residence has \(roomCount) room(s).")
} else {
print("Unable to retrieve the number of rooms.")
}
// 打印“Unable to retrieve the number of rooms.”
也可以通過訪問屬性來設定屬性值
let someAddress = Address()
someAddress.buildingNumber = "29"
someAddress.street = "Acacia Road"
john.residence?.address = someAddress
可以通過可選鏈來調用方法,並判別是否調用成功,即使那個沒有返回值。
func printNumberOfRooms() {
print("The number of rooms is \(numberOfRooms)")
}
也可以用另一個方式看回傳值是否為 nil 來判別是否調用成功
if john.residence?.printNumberOfRooms() != nil {
print("It was possible to print the number of rooms.")
} else {
print("It was not possible to print the number of rooms.")
}
// 打印“It was not possible to print the number of rooms.”
也可以用訪問下標的方式在可選值上使用,並判別下標調用是否成功。
if let firstRoomName = john.residence?[0].name {
print("The first room name is \(firstRoomName).")
} else {
print("Unable to retrieve the first room name.")
}
// 打印“Unable to retrieve the first room name.”
因為 john.residence 是 nil 所以失敗。
今天就到這裡了,感謝大家。